package main

import "fmt"

/**
【1】接口本身不能创建实例，但是可以指向一个实现了该接口的自定义类型的变量。
【2】只要是自定义数据类型，就可以实现接口，不仅仅是结构体类型。
【3】一个自定义类型可以实现多个接口
【4]一个接口(比如A接口)可以继承多个别的接口(比如B,c接口)，这时如果要实现A接口,也必须将B,C接口的方法也全部实现。
【5】interface类型默认是一个指针(引用类型)，如果没有对interface初始化就使用,那么会输出nil
【6】空接口没有任何方法,所以可以理解为所有类型都实现了空接口，也可以理解为我们可以把如何一个变量赋给空接口。
**/

type SayHello interface {
	// 声明没有实现的方法：
	SayHello()
}

// 接口实现
type Chinese struct {
}

// 具体实现接口的方法
func (c *Chinese) SayHello() {
	fmt.Println("你好，中国!")
}

// 美国人实现
type American struct {
}

func (a *American) SayHello() {
	fmt.Println("你好，美国!")
}

// 定义一个函数：专门用户各国人打招呼
func SayHelloTo(sayHello SayHello) {
	sayHello.SayHello()
}

// 空接口
type E interface {
}

func main() {
	var c Chinese
	var a American
	SayHelloTo(&c)
	SayHelloTo(&a)

	var i integer
	i = 10
	i.sayHello()

	stu := Stu{}
	stu.a()
	stu.b()
	stu.c()

	var e E = stu
	fmt.Println(e)

	// 空接口可以接受任何类型变量
	var e2 interface{} = stu
	fmt.Println(e2)
}

//-------------------
// 自定义数据类型
type integer int

func (i integer) sayHello() {
	fmt.Println("integer sayHello == ", i)
}

//-------------------
// 实现多个接口
type AInterface interface {
	a()
}

type BInterface interface {
	b()
}
type CInterface interface {
	BInterface
	c()
}
type Stu struct {
}

func (s *Stu) a() {
	fmt.Println("a")
}
func (s *Stu) b() {
	fmt.Println("b")
}
func (s *Stu) c() {
	fmt.Println("c")
}

// ------------------------
